<template>
  <div class="app-container">
    <el-tabs v-model="activeTab" type="border-card">
      <el-tab-pane label="基础信息" name="basic">
        <el-form ref="form" :model="form" label-width="120px">
          <el-form-item label="服务器ID">
            <span>{{ form.serverId }}</span>
          </el-form-item>
          <el-form-item label="服务器名称">
            <span>{{ form.serverName }}</span>
          </el-form-item>
          <el-form-item label="IP地址">
            <span>{{ form.ipAddress }}</span>
          </el-form-item>
          <el-form-item label="端口">
            <span>{{ form.port }}</span>
          </el-form-item>
          <el-form-item label="用户名">
            <span>{{ form.userName }}</span>
          </el-form-item>
          <el-form-item label="状态">
            <dict-tag :options="dict.type.sys_normal_disable" :value="form.status"/>
          </el-form-item>
          <el-form-item label="创建时间">
            <span>{{ parseTime(form.createTime) }}</span>
          </el-form-item>
          <el-form-item label="备注">
            <span>{{ form.remark }}</span>
          </el-form-item>
        </el-form>
      </el-tab-pane>

      <el-tab-pane label="命令执行" name="command">
        <el-form>
          <el-form-item>
            <el-input
              type="textarea"
              :rows="3"
              placeholder="请输入Linux命令"
              v-model="commandInput"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="runCommand">执行命令</el-button>
            <el-button @click="clearCommand">清空</el-button>
          </el-form-item>
        </el-form>

        <div v-if="commandOutput" class="command-output">
          <div class="output-header">命令输出:</div>
          <pre class="output-content">{{ commandOutput }}</pre>
        </div>
      </el-tab-pane>

      <el-tab-pane label="进程管理" name="process">
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-refresh"
              size="mini"
              @click="getProcessList"
            >刷新</el-button>
          </el-col>
        </el-row>

        <el-table v-loading="processLoading" :data="processList" style="width: 100%">
          <el-table-column label="PID" prop="pid" width="80" />
          <el-table-column label="用户" prop="uid" width="100" />
          <el-table-column label="CPU" prop="cpu" width="60" />
          <el-table-column label="开始时间" prop="startTime" width="120" />
          <el-table-column label="TTY" prop="tty" width="80" />
          <el-table-column label="命令" prop="command" />
          <el-table-column label="操作" align="center" width="100">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                icon="el-icon-delete"
                @click="handleKillProcess(scope.row)"
              >终止</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>

      <el-tab-pane label="文件管理" name="file">
        <el-row :gutter="10" class="mb8">
          <el-col :span="8">
            <el-input
              placeholder="当前路径"
              v-model="currentPath"
              readonly
            >
              <el-button slot="append" icon="el-icon-back" @click="navigateUp"></el-button>
            </el-input>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-refresh"
              size="mini"
              @click="refreshFiles"
            >刷新</el-button>
          </el-col>
        </el-row>

        <el-table v-loading="fileLoading" :data="fileList" style="width: 100%">
          <el-table-column label="" width="40">
            <template slot-scope="scope">
              <i class="el-icon-folder" v-if="scope.row.isDirectory"></i>
              <i class="el-icon-document" v-else></i>
            </template>
          </el-table-column>
          <el-table-column prop="name" label="名称">
            <template slot-scope="scope">
              <el-link
                type="primary"
                :underline="false"
                v-if="scope.row.isDirectory"
                @click="navigateToDirectory(scope.row.path)">
                {{ scope.row.name }}
              </el-link>
              <span v-else>{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="180">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="primary"
                icon="el-icon-copy-document"
                @click="handleSyncFile(scope.row)">同步至其他服务器</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>

      <el-tab-pane label="Docker管理" name="docker">
        <el-tabs v-model="dockerActiveTab">
          <el-tab-pane label="SSH免密登录" name="ssh">
            <el-form :model="sshKeyAuthForm" label-width="120px">
              <el-form-item label="源服务器">
                <el-input v-model="form.serverName" disabled />
              </el-form-item>
              <el-form-item label="目标服务器">
                <el-select v-model="sshKeyAuthForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
                  <el-option
                    v-for="server in targetServers"
                    :key="server.serverId"
                    :label="server.serverName"
                    :value="server.serverId"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="setupSSHKeyAuth" :loading="sshKeyAuthLoading">设置SSH免密登录</el-button>
              </el-form-item>
            </el-form>

            <div v-if="sshKeyAuthResult" class="ssh-result">
              <el-alert
                :title="sshKeyAuthResult.message"
                :type="sshKeyAuthResult.success ? 'success' : 'error'"
                :description="generateSSHResultDescription(sshKeyAuthResult)"
                show-icon
                :closable="false"
              >
              </el-alert>
            </div>
          </el-tab-pane>

          <el-tab-pane label="容器管理" name="containers">
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-refresh"
                  size="mini"
                  @click="getContainerList"
                >刷新</el-button>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="success"
                  plain
                  icon="el-icon-share"
                  size="mini"
                  @click="showMigrateAllContainersDialog"
                >一键迁移所有容器</el-button>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="success"
                  plain
                  icon="el-icon-document"
                  size="mini"
                  @click="handleGenerateAllCompose"
                >导出所有容器</el-button>
              </el-col>
            </el-row>

            <el-table v-loading="dockerContainersLoading" :data="dockerContainers" style="width: 100%">
              <el-table-column label="容器ID" prop="ID" width="100" />
              <el-table-column label="名称" prop="Names" />
              <el-table-column label="镜像" prop="Image" />
              <el-table-column label="状态" prop="Status" />
              <el-table-column label="端口" prop="Ports" />
              <el-table-column label="操作" align="center" width="330">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-view"
                    @click="handleInspectContainer(scope.row)"
                  >详情</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-video-play"
                    @click="handleStartContainer(scope.row)"
                    v-if="scope.row.Status && scope.row.Status.indexOf('Exited') !== -1"
                  >启动</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-video-pause"
                    @click="handleStopContainer(scope.row)"
                    v-if="scope.row.Status && scope.row.Status.indexOf('Up') !== -1"
                  >停止</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-tickets"
                    @click="handleContainerLogs(scope.row)"
                  >日志</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-delete"
                    @click="handleRemoveContainer(scope.row)"
                  >删除</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-share"
                    @click="handleMigrateContainer(scope.row)"
                  >迁移</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-document"
                    @click="handleGenerateCompose(scope.row)"
                  >导出Compose</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>

          <el-tab-pane label="镜像管理" name="images">
            <el-row :gutter="10" class="mb8">
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-refresh"
                  size="mini"
                  @click="getImageList"
                >刷新</el-button>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="success"
                  plain
                  icon="el-icon-share"
                  size="mini"
                  @click="showMigrateAllImagesDialog"
                >一键迁移所有镜像</el-button>
              </el-col>
            </el-row>

            <el-table v-loading="dockerImagesLoading" :data="dockerImages" style="width: 100%">
              <el-table-column label="仓库" prop="Repository" />
              <el-table-column label="标签" prop="Tag" />
              <el-table-column label="镜像ID" prop="ID" width="100" />
              <el-table-column label="大小" prop="Size" />
              <el-table-column label="创建时间" prop="CreatedAt" />
              <el-table-column label="操作" align="center" width="100">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-share"
                    @click="handleMigrateImage(scope.row)"
                  >迁移</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>

          <el-tab-pane label="Compose管理" name="compose">
            <el-alert
              v-if="!composeInstalled"
              title="未检测到Docker Compose，请先安装"
              type="warning"
              show-icon>
              <div style="margin-top: 10px;">
                <el-select v-model="composeVersion" placeholder="选择版本" style="width: 150px; margin-right: 10px;">
                  <el-option label="v2.25.0 (默认)" value="v2.25.0"></el-option>
                  <el-option label="v2.24.6" value="v2.24.6"></el-option>
                  <el-option label="v2.23.3" value="v2.23.3"></el-option>
                  <el-option label="v2.22.0" value="v2.22.0"></el-option>
                  <el-option label="v2.20.3" value="v2.20.3"></el-option>
                  <el-option label="v2.18.1" value="v2.18.1"></el-option>
                  <el-option label="v2.16.0" value="v2.16.0"></el-option>
                  <el-option label="v1.29.2" value="v1.29.2"></el-option>
                  <el-option label="v1.25.0" value="v1.25.0"></el-option>
                </el-select>
                <el-radio-group v-model="composeInstallMethod" style="margin-right: 10px;">
                  <el-radio label="user">为当前用户安装</el-radio>
                  <el-radio label="system">为所有用户安装</el-radio>
                </el-radio-group>
                <el-button type="primary" @click="installDockerComposeHandler">立即安装</el-button>
              </div>
            </el-alert>

            <el-alert
              v-if="composeInstalled && composeInstallDetails"
              title="Docker Compose已安装"
              type="success"
              show-icon
              :closable="false"
              style="margin-bottom: 10px;">
              <div>
                <p><strong>版本信息：</strong> {{ composeInstallDetails.version }}</p>
                <p v-if="composeInstallDetails.details && composeInstallDetails.details.location"><strong>安装位置：</strong> <pre style="margin: 5px 0; padding: 5px; background: #f5f5f5; border-radius: 4px;">{{ composeInstallDetails.details.location }}</pre></p>
                <p v-if="composeInstallDetails.details && composeInstallDetails.details.permissions"><strong>权限信息：</strong> <pre style="margin: 5px 0; padding: 5px; background: #f5f5f5; border-radius: 4px;">{{ composeInstallDetails.details.permissions }}</pre></p>
                <p v-if="composeInstallDetails.details && composeInstallDetails.details.symlink"><strong>软链接信息：</strong> <pre style="margin: 5px 0; padding: 5px; background: #f5f5f5; border-radius: 4px;">{{ composeInstallDetails.details.symlink }}</pre></p>
                <el-button size="small" type="primary" @click="checkComposeInstalled">刷新安装信息</el-button>
              </div>
            </el-alert>

            <el-input
              prefix-icon="el-icon-search"
              v-model="composeSearchPath"
              placeholder="输入目录路径搜索 Compose 文件，如: /"
              @keyup.enter.native="searchComposeFiles"
              style="margin-bottom: 10px; width: 50%;">
              <el-button slot="append" icon="el-icon-search" @click="searchComposeFiles"></el-button>
            </el-input>

            <el-table v-loading="composeFilesLoading" :data="composeFiles" style="width: 100%">
              <el-table-column label="路径" prop="path" />
              <el-table-column label="目录" prop="directory" />
              <el-table-column label="操作" align="center" width="260">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    icon="el-icon-view"
                    @click="handleViewComposeFile(scope.row.path)">查看</el-button>
                  <el-button
                    size="mini"
                    type="success"
                    icon="el-icon-video-play"
                    @click="handleRunCompose(scope.row.path, 'up')">启动</el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    icon="el-icon-video-pause"
                    @click="handleRunCompose(scope.row.path, 'down')">停止</el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    icon="el-icon-delete"
                    @click="handleDeleteComposeFile(scope.row.path)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>

          <!-- 添加一个容器模板标签页 -->
          <el-tab-pane label="容器模板" name="template">
            <el-table v-loading="templateLoading" :data="dockerTemplates" style="width: 100%">
              <el-table-column label="模板名称" prop="templateName" />
              <el-table-column label="镜像" prop="imageName" />
              <el-table-column label="描述" prop="templateDescription" :show-overflow-tooltip="true" />
              <el-table-column label="操作" align="center" width="200">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    @click="handleDeployTemplate(scope.row)"
                  >部署</el-button>
                  <el-button
                    size="mini"
                    type="success"
                    @click="handleViewTemplate(scope.row)"
                  >查看</el-button>
                </template>
              </el-table-column>
            </el-table>
            <div style="margin-top: 10px;">
              <el-button type="primary" @click="goToTemplateManage">管理模板</el-button>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-tab-pane>

      <el-tab-pane label="软件管理" name="software">
        <el-tabs v-model="softwareActiveTab">
          <el-tab-pane label="已安装软件" name="installed">
            <el-row :gutter="10" class="mb8">
              <el-col :span="6">
                <el-input
                  placeholder="搜索软件包"
                  v-model="installedSearchKeyword"
                  clearable
                >
                  <el-button slot="append" icon="el-icon-search" @click="searchInstalledSoftware"></el-button>
                </el-input>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-refresh"
                  size="mini"
                  @click="getInstalledSoftwareList"
                >刷新</el-button>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="success"
                  plain
                  icon="el-icon-download"
                  size="mini"
                  @click="showUpdateAllDialog"
                >全部更新</el-button>
              </el-col>
            </el-row>

            <el-table v-loading="installedSoftwareLoading" :data="installedSoftwareList" style="width: 100%">
              <el-table-column label="软件包名" prop="name" />
              <el-table-column label="版本" prop="version" width="100" />
              <el-table-column label="描述" prop="description" />
              <el-table-column label="操作" align="center" width="180">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-refresh"
                    @click="handleUpdateSoftware(scope.row)"
                  >更新</el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-delete"
                    @click="handleUninstallSoftware(scope.row)"
                  >卸载</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>

          <el-tab-pane label="可用软件" name="available">
            <el-row :gutter="10" class="mb8">
              <el-col :span="6">
                <el-input
                  placeholder="搜索软件包"
                  v-model="availableSearchKeyword"
                  clearable
                >
                  <el-button slot="append" icon="el-icon-search" @click="searchAvailableSoftware"></el-button>
                </el-input>
              </el-col>
              <el-col :span="1.5">
                <el-button
                  type="primary"
                  plain
                  icon="el-icon-refresh"
                  size="mini"
                  @click="getAvailableSoftwareList"
                >刷新</el-button>
              </el-col>
            </el-row>

            <el-table v-loading="availableSoftwareLoading" :data="availableSoftwareList" style="width: 100%">
              <el-table-column label="软件包名" prop="name" />
              <el-table-column label="版本" prop="version" width="100" />
              <el-table-column label="描述" prop="description" />
              <el-table-column label="操作" align="center" width="100">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-download"
                    @click="handleInstallSoftware(scope.row)"
                  >安装</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>
        </el-tabs>
      </el-tab-pane>
    </el-tabs>

    <!-- 容器详情弹窗 -->
    <el-dialog title="容器详情" :visible.sync="containerDetailVisible" width="80%">
      <pre class="detail-content">{{ containerDetailContent }}</pre>
    </el-dialog>

    <!-- Compose文件内容弹窗 -->
    <el-dialog title="Compose文件内容" :visible.sync="composeFileContentVisible" width="80%">
      <pre class="detail-content" v-if="composeFileContent">{{ composeFileContent }}</pre>
      <div v-else class="empty-content">没有内容可显示</div>
    </el-dialog>

    <!-- 迁移容器弹窗 -->
    <el-dialog title="迁移容器" :visible.sync="migrateContainerVisible" width="50%">
      <el-form :model="migrateContainerForm" label-width="120px">
        <el-form-item label="源服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="migrateContainerForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="容器">
          <el-input v-model="migrateContainerForm.containerName" disabled />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitMigrateContainer" :loading="migrateLoading">确定</el-button>
        <el-button @click="migrateContainerVisible = false">取消</el-button>
      </div>
    </el-dialog>

    <!-- 迁移Compose弹窗 -->
    <el-dialog title="迁移Compose" :visible.sync="migrateComposeVisible" width="50%">
      <el-form :model="migrateComposeForm" label-width="120px">
        <el-form-item label="源服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="migrateComposeForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="Compose目录">
          <el-input v-model="migrateComposeForm.composePath" disabled />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitMigrateCompose" :loading="migrateLoading">确定</el-button>
        <el-button @click="migrateComposeVisible = false">取消</el-button>
      </div>
    </el-dialog>

    <!-- 软件安装进度弹窗 -->
    <el-dialog title="软件安装进度" :visible.sync="softwareOperationVisible" width="60%" :close-on-click-modal="false">
      <div v-if="softwareOperationLogs.length === 0" class="empty-logs">
        <span>正在准备...</span>
      </div>
      <div v-else class="operation-logs">
        <pre class="logs-content">{{ softwareOperationLogs }}</pre>
      </div>
      <el-progress :percentage="softwareOperationProgress" :status="softwareOperationStatus"></el-progress>
      <div slot="footer" class="dialog-footer">
        <el-button @click="closeSoftwareOperation" :disabled="softwareOperationRunning">关闭</el-button>
      </div>
    </el-dialog>

    <!-- 镜像迁移弹窗 -->
    <el-dialog title="迁移镜像" :visible.sync="migrateImageVisible" width="50%">
      <el-form :model="migrateImageForm" label-width="120px">
        <el-form-item label="源服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="migrateImageForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="镜像">
          <el-input v-model="migrateImageForm.imageName" disabled />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitMigrateImage" :loading="migrateLoading">确定</el-button>
        <el-button @click="migrateImageVisible = false">取消</el-button>
      </div>
    </el-dialog>

    <!-- 迁移所有容器弹窗 -->
    <el-dialog title="迁移所有容器" :visible.sync="migrateAllContainersVisible" width="50%">
      <el-form :model="migrateAllContainersForm" label-width="120px">
        <el-form-item label="源服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="migrateAllContainersForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-alert
          title="此操作将迁移服务器上所有正在运行的Docker容器，可能需要较长时间，请确认。"
          type="warning"
          :closable="false"
          show-icon
        />
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitMigrateAllContainers" :loading="migrateLoading">确定</el-button>
        <el-button @click="migrateAllContainersVisible = false">取消</el-button>
      </div>
    </el-dialog>

    <!-- 迁移所有镜像弹窗 -->
    <el-dialog title="迁移所有镜像" :visible.sync="migrateAllImagesVisible" width="50%">
      <el-form :model="migrateAllImagesForm" label-width="120px">
        <el-form-item label="源服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="migrateAllImagesForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-alert
          title="此操作将迁移服务器上所有Docker镜像，可能需要较长时间，请确认。"
          type="warning"
          :closable="false"
          show-icon
        />
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitMigrateAllImages" :loading="migrateLoading">确定</el-button>
        <el-button @click="migrateAllImagesVisible = false">取消</el-button>
      </div>
    </el-dialog>

    <!-- 容器日志弹窗 -->
    <el-dialog title="容器日志" :visible.sync="containerLogsVisible" width="80%">
      <el-form :inline="true" class="container-logs-form">
        <el-form-item label="日志行数">
          <el-input-number v-model="containerLogsLines" :min="10" :max="1000" :step="10"></el-input-number>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="refreshContainerLogs">刷新</el-button>
        </el-form-item>
      </el-form>
      <pre class="detail-content">{{ containerLogsContent }}</pre>
    </el-dialog>

    <!-- 生成Docker Compose文件弹窗 -->
    <el-dialog title="生成Docker Compose文件" :visible.sync="generateComposeVisible" width="500px" append-to-body>
      <el-form :model="generateComposeForm" label-width="120px">
        <el-form-item label="容器ID">
          <el-input v-model="generateComposeForm.containerId" disabled />
        </el-form-item>
        <el-form-item label="容器名称">
          <el-input v-model="generateComposeForm.containerName" disabled />
        </el-form-item>
        <el-form-item label="输出路径">
          <el-input v-model="generateComposeForm.outputPath" placeholder="例如：/root/compose/docker-compose.yml" />
        </el-form-item>
        <el-form-item label="导出范围">
          <el-radio-group v-model="generateComposeForm.allContainers">
            <el-radio :label="false">仅当前容器</el-radio>
            <el-radio :label="true">所有运行中容器</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="generateComposeVisible = false">取 消</el-button>
        <el-button type="primary" :loading="generateComposeLoading" @click="submitGenerateCompose">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 添加文件同步对话框 -->
    <el-dialog title="同步文件至其他服务器" :visible.sync="syncFileVisible" width="500px">
      <el-form :model="syncFileForm" label-width="100px">
        <el-form-item label="当前服务器">
          <el-input v-model="form.serverName" disabled />
        </el-form-item>
        <el-form-item label="源文件路径">
          <el-input v-model="syncFileForm.sourcePath" disabled />
        </el-form-item>
        <el-form-item label="源文件类型">
          <el-tag type="info">{{ syncFileForm.isDirectory ? '目录' : '文件' }}</el-tag>
        </el-form-item>
        <el-form-item label="目标服务器">
          <el-select v-model="syncFileForm.targetServerId" placeholder="请选择目标服务器" style="width: 100%">
            <el-option
              v-for="server in targetServers"
              :key="server.serverId"
              :label="server.serverName"
              :value="server.serverId"
              :disabled="server.serverId === serverId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="目标路径">
          <el-input v-model="syncFileForm.targetPath" placeholder="请输入目标路径" />
        </el-form-item>
        <el-form-item v-if="syncFileForm.isDirectory">
          <el-alert
            title="将同步目录下的所有文件，可能需要较长时间，请确认。"
            type="warning"
            :closable="false"
            show-icon
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="syncFileVisible = false">取消</el-button>
        <el-button type="primary" :loading="syncLoading" @click="submitSyncFile">同步</el-button>
      </div>
    </el-dialog>

    <!-- 容器名称冲突解决对话框 -->
    <el-dialog title="容器名称冲突" :visible.sync="containerConflictVisible" width="500px">
      <el-alert
        title="检测到容器名称冲突"
        type="warning"
        description="服务器上已存在同名容器，请选择处理方式"
        show-icon
        :closable="false"
        style="margin-bottom: 20px;"
      />
      <el-form :model="containerConflictForm" label-width="120px">
        <el-form-item label="冲突容器名">
          <el-input v-model="containerConflictForm.containerName" disabled />
        </el-form-item>
        <el-form-item label="处理方式">
          <el-radio-group v-model="containerConflictForm.action">
            <el-radio label="rename">重命名新容器</el-radio>
            <el-radio label="remove">删除原有容器</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="新容器名称" v-if="containerConflictForm.action === 'rename'">
          <el-input v-model="containerConflictForm.newName" placeholder="请输入新容器名称" />
        </el-form-item>
        <el-form-item label="修改端口" v-if="containerConflictForm.action === 'rename'">
          <el-switch v-model="containerConflictForm.changePort" />
        </el-form-item>
        <el-form-item label="端口映射" v-if="containerConflictForm.action === 'rename' && containerConflictForm.changePort">
          <el-input v-model="containerConflictForm.portMapping" placeholder="例如：8080:80,9000:3000" />
          <div class="el-form-item-msg">格式：主机端口:容器端口，多个映射用逗号分隔</div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="containerConflictVisible = false">取消</el-button>
        <el-button type="primary" @click="handleResolveContainerConflict" :loading="containerConflictLoading">确定</el-button>
      </div>
    </el-dialog>

    <!-- 添加部署容器模板对话框 -->
    <el-dialog :title="'部署容器模板 - ' + templateForm.templateName" :visible.sync="templateDeployVisible" width="500px" append-to-body>
      <el-form ref="templateForm" :model="templateForm" :rules="templateRules" label-width="100px">
        <el-form-item label="容器名称" prop="containerName">
          <el-input v-model="templateForm.containerName" placeholder="请输入容器名称，留空则自动生成" />
        </el-form-item>
        <el-collapse>
          <el-collapse-item title="自定义参数（可选）">
            <el-form-item label="端口映射">
              <el-input v-model="templateForm.customParams.portMappings" placeholder="格式: 宿主机端口:容器端口,分隔。留空则使用模板默认值" />
            </el-form-item>
            <el-form-item label="卷映射">
              <el-input v-model="templateForm.customParams.volumeMappings" placeholder="格式: 宿主机路径:容器路径,分隔。留空则使用模板默认值" />
            </el-form-item>
            <el-form-item label="环境变量">
              <el-input v-model="templateForm.customParams.environmentVars" placeholder="格式: 变量名=变量值,分隔。留空则使用模板默认值" />
            </el-form-item>
          </el-collapse-item>
        </el-collapse>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitTemplateForm" :loading="templateDeployLoading">部 署</el-button>
        <el-button @click="cancelTemplateDeploy">取 消</el-button>
      </div>
    </el-dialog>
    
    <!-- 添加查看容器模板详情对话框 -->
    <el-dialog :title="'模板详情 - ' + selectedTemplate.templateName" :visible.sync="templateDetailVisible" width="600px" append-to-body>
      <el-descriptions border :column="1" size="medium">
        <el-descriptions-item label="模板名称">{{ selectedTemplate.templateName }}</el-descriptions-item>
        <el-descriptions-item label="模板描述">{{ selectedTemplate.templateDescription }}</el-descriptions-item>
        <el-descriptions-item label="镜像">{{ selectedTemplate.imageName }}:{{ selectedTemplate.imageTag }}</el-descriptions-item>
        <el-descriptions-item label="端口映射">{{ selectedTemplate.portMappings || '无' }}</el-descriptions-item>
        <el-descriptions-item label="卷映射">{{ selectedTemplate.volumeMappings || '无' }}</el-descriptions-item>
        <el-descriptions-item label="环境变量">{{ selectedTemplate.environmentVars || '无' }}</el-descriptions-item>
        <el-descriptions-item label="网络模式">{{ selectedTemplate.networkMode }}</el-descriptions-item>
        <el-descriptions-item label="重启策略">{{ selectedTemplate.restartPolicy }}</el-descriptions-item>
        <el-descriptions-item label="启动命令">{{ selectedTemplate.command || '无' }}</el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script>
import {
  getServer,
  executeCommand,
  getServerProcesses,
  killServerProcess,
  listServerOptions,
  listServerFiles,
  getDockerContainers,
  getDockerImages,
  getDockerComposeFiles,
  readDockerComposeFile,
  migrateDockerContainer,
  migrateDockerCompose,
  migrateAllDockerContainers,
  migrateDockerImage,
  getAvailableSoftwarePackages,
  getInstalledSoftwarePackages,
  installSoftwarePackage,
  uninstallSoftwarePackage,
  updateSoftwarePackage,
  setupSSHKeyAuth,
  startDockerContainer,
  stopDockerContainer,
  removeDockerContainer,
  getDockerContainerLogs,
  installDockerCompose,
  generateDockerCompose,
  runDockerCompose,
  syncFileBetweenServers
} from "@/api/datasync/server";
import { parseTime } from '@/utils/ruoyi';
import {
  listDockerTemplate,
  createContainerFromTemplate
} from "@/api/system/dockerTemplate";

export default {
  name: "ServerDetail",
  dicts: ['sys_normal_disable'],
  data() {
    return {
      // 服务器ID
      serverId: null,
      // 当前标签页
      activeTab: "basic",
      dockerActiveTab: "ssh",
      // 表单对象
      form: {},
      // 命令输入框
      commandInput: '',
      // 命令输出
      commandOutput: '',
      // 当前路径
      currentPath: '/',
      // 文件列表
      fileList: [],
      // 文件加载中
      fileLoading: false,
      // 进程列表
      processList: [],
      // 进程加载中
      processLoading: false,

      // Docker管理相关
      dockerContainers: [],
      dockerContainersLoading: false,
      dockerImages: [],
      dockerImagesLoading: false,
      composeDirPath: '/',
      composeFiles: [],
      composeFilesLoading: false,

      // 弹窗相关
      containerDetailVisible: false,
      containerDetailContent: '',
      composeFileContentVisible: false,
      composeFileContent: '',
      migrateContainerVisible: false,
      migrateComposeVisible: false,
      migrateLoading: false,
      migrateContainerForm: {
        targetServerId: null,
        containerId: '',
        containerName: ''
      },
      migrateComposeForm: {
        targetServerId: null,
        composePath: ''
      },
      targetServers: [],

      // 软件管理相关
      softwareActiveTab: 'installed',
      installedSoftwareList: [],
      installedSoftwareLoading: false,
      availableSoftwareList: [],
      availableSoftwareLoading: false,
      installedSearchKeyword: '',
      availableSearchKeyword: '',

      // 软件操作相关
      softwareOperationVisible: false,
      softwareOperationLogs: '',
      softwareOperationProgress: 0,
      softwareOperationStatus: '',
      softwareOperationRunning: false,
      softwareOperationTimer: null,

      // 镜像迁移相关
      migrateImageVisible: false,
      migrateImageForm: {
        targetServerId: null,
        imageId: '',
        imageName: ''
      },

      // 迁移所有容器相关
      migrateAllContainersVisible: false,
      migrateAllContainersForm: {
        targetServerId: null
      },

      // 迁移所有镜像相关
      migrateAllImagesVisible: false,
      migrateAllImagesForm: {
        targetServerId: null
      },

      // SSH免密登录相关
      sshKeyAuthForm: {
        targetServerId: null
      },
      sshKeyAuthResult: null,
      sshKeyAuthLoading: false,

      // 容器日志相关
      containerLogsVisible: false,
      containerLogsContent: '',
      containerLogsLines: 100,
      currentContainerId: '',

      // Docker Compose相关
      composeInstalled: false,
      composeSearchPath: '/',

      // 添加运行Docker Compose的相关状态
      runComposeLoading: false,

      // 生成Compose文件相关
      generateComposeVisible: false,
      generateComposeLoading: false,
      generateComposeForm: {
        containerId: '',
        containerName: '',
        outputPath: '/root/compose/docker-compose.yml',
        allContainers: false
      },

      // 文件同步相关
      syncFileVisible: false,
      syncLoading: false,
      syncFileForm: {
        sourcePath: '',
        targetServerId: null,
        targetPath: '',
        isDirectory: false
      },

      // Compose版本相关
      composeVersion: 'v2.25.0',
      composeInstallMethod: 'user',
      composeInstallDetails: null,

      // 添加容器冲突相关状态
      containerConflictVisible: false,
      containerConflictLoading: false,
      containerConflictForm: {
        containerName: '',
        action: 'rename',
        newName: '',
        changePort: false,
        portMapping: '',
        composeFilePath: '',
        operation: ''
      },

      // Docker容器模板相关
      dockerTemplates: [],
      templateLoading: false,
      templateDeployVisible: false,
      templateDeployLoading: false,
      templateDetailVisible: false,
      selectedTemplate: {},
      templateForm: {
        templateId: null,
        templateName: '',
        containerName: '',
        customParams: {
          portMappings: '',
          volumeMappings: '',
          environmentVars: ''
        }
      },
      templateRules: {
        // 没有必填字段，容器名称可以为空，系统会自动生成
      }
    };
  },
  created() {
    this.serverId = parseInt(this.$route.query.serverId);
    if (!this.serverId) {
      this.$message.error('服务器ID不能为空');
      return;
    }
    this.getServerInfo();
    this.loadTargetServers();
  },
  watch: {
    dockerActiveTab(newVal) {
      if (newVal === 'compose') {
        // 切换到Compose标签页时检查Docker Compose是否安装
        this.checkComposeInstalled();
      }
      if (newVal === 'template') {
        this.getDockerTemplates();
      }
    }
  },
  methods: {
    /** 获取服务器信息 */
    getServerInfo() {
      getServer(this.serverId).then(response => {
        if (response.code === 200) {
          this.form = response.data;
        }
      });
    },

    /** 执行命令 */
    runCommand() {
      if (!this.commandInput) {
        this.$message.error('请输入要执行的命令');
        return;
      }

      this.$modal.loading("正在执行命令...");
      executeCommand(this.serverId, this.commandInput).then(response => {
        this.$modal.closeLoading();
        if (response.code === 200) {
          const data = response.data;
          if (data.success) {
            let output = '';
            if (data.stdout) {
              output += data.stdout;
            }
            if (data.stderr) {
              if (output) output += '\n';
              output += '错误: ' + data.stderr;
            }
            this.commandOutput = output || '命令执行成功，无输出';
          } else {
            this.commandOutput = '执行错误: ' + (data.message || '未知错误');
          }
        } else {
          this.commandOutput = '请求错误: ' + response.msg;
        }
      }).catch(() => {
        this.$modal.closeLoading();
        this.commandOutput = '请求异常，请稍后重试';
      });
    },

    /** 清空命令 */
    clearCommand() {
      this.commandInput = '';
      this.commandOutput = '';
    },

    /** 获取进程列表 */
    getProcessList() {
      this.processLoading = true;
      getServerProcesses(this.serverId).then(response => {
        this.processLoading = false;
        if (response.code === 200) {
          this.processList = response.data;
        }
      }).catch(() => {
        this.processLoading = false;
      });
    },

    /** 终止进程 */
    handleKillProcess(row) {
      this.$modal.confirm('确认要终止进程 ' + row.pid + ' (' + row.command + ') 吗？').then(() => {
        this.$modal.loading("正在终止进程...");
        killServerProcess(this.serverId, row.pid).then(response => {
          this.$modal.closeLoading();
          if (response.code === 200) {
            this.$message.success('进程终止成功');
            this.getProcessList(); // 刷新进程列表
          } else {
            this.$message.error(response.msg || '进程终止失败');
          }
        }).catch(() => {
          this.$modal.closeLoading();
        });
      });
    },

    /** 刷新文件列表 */
    refreshFiles() {
      this.loadDirectoryContents(this.currentPath);
    },

    /** 加载目录内容 */
    loadDirectoryContents(dirPath) {
      this.fileLoading = true;
      listServerFiles(this.serverId, dirPath).then(response => {
        this.fileLoading = false;
        if (response.code === 200) {
          this.fileList = response.data;
          this.currentPath = dirPath;
        } else {
          this.$message.error('加载目录内容失败: ' + response.msg);
        }
      }).catch(() => {
        this.fileLoading = false;
      });
    },

    /** 导航到指定目录 */
    navigateToDirectory(dirPath) {
      this.loadDirectoryContents(dirPath);
    },

    /** 导航到上级目录 */
    navigateUp() {
      if (this.currentPath === '/') {
        return;
      }

      const lastSlashIndex = this.currentPath.lastIndexOf('/');
      if (lastSlashIndex === 0) {
        this.loadDirectoryContents('/');
      } else {
        const parentPath = this.currentPath.substring(0, lastSlashIndex);
        this.loadDirectoryContents(parentPath);
      }
    },

    /** 获取Docker容器列表 */
    getContainerList() {
      this.dockerContainersLoading = true;
      getDockerContainers(this.serverId).then(response => {
        this.dockerContainersLoading = false;
        if (response.code === 200) {
          this.dockerContainers = response.data;
        } else {
          this.$message.error('获取容器列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.dockerContainersLoading = false;
        this.$message.error('获取容器列表失败');
      });
    },

    /** 获取Docker镜像列表 */
    getImageList() {
      this.dockerImagesLoading = true;
      getDockerImages(this.serverId).then(response => {
        this.dockerImagesLoading = false;
        if (response.code === 200) {
          this.dockerImages = response.data;
        } else {
          this.$message.error('获取镜像列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.dockerImagesLoading = false;
        this.$message.error('获取镜像列表失败');
      });
    },

    /** 搜索Compose文件 */
    searchComposeFiles() {
      this.composeFilesLoading = true;
      getDockerComposeFiles(this.serverId, this.composeSearchPath).then(response => {
        this.composeFilesLoading = false;
        if (response.code === 200) {
          this.composeFiles = response.data;
        } else {
          this.composeFiles = [];
          this.$message.error('获取Docker Compose文件列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.composeFilesLoading = false;
        this.composeFiles = [];
        this.$message.error('获取Docker Compose文件列表失败，请检查网络连接');
      });
    },

    /** 查看容器详情 */
    handleInspectContainer(row) {
      if (!row || !row.ID) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.$modal.loading('正在获取容器详情...');

      executeCommand(this.serverId, 'docker inspect ' + row.ID).then(response => {
        this.$modal.closeLoading();
        if (response.code === 200 && response.data.success) {
          this.containerDetailContent = response.data.stdout;
          this.containerDetailVisible = true;
        } else {
          this.$message.error('获取容器详情失败: ' + (response.data ? response.data.stderr : response.msg));
        }
      }).catch(() => {
        this.$modal.closeLoading();
        this.$message.error('获取容器详情失败');
      });
    },

    /** 查看Docker Compose文件内容 */
    handleViewComposeFile(filePath) {
      this.composeFileContentVisible = true
      this.composeFileContent = '加载中...'

      readDockerComposeFile(this.serverId, filePath).then(response => {
        if (response.code === 200) {
          // Check if the content is in response.data or response.msg
          if (response.msg && typeof response.msg === 'string' && response.msg.includes('version:')) {
            this.composeFileContent = response.msg
          } else {
            this.composeFileContent = response.data || ''
          }
          
          if (!this.composeFileContent) {
            this.composeFileContent = '文件内容为空'
          }
        } else {
          this.composeFileContent = '读取文件失败: ' + response.msg
        }
      }).catch(() => {
        this.composeFileContent = '读取文件失败'
      })
    },

    /** 显示迁移容器弹窗 */
    handleMigrateContainer(row) {
      this.migrateContainerForm = {
        targetServerId: null,
        containerId: row.ID,
        containerName: row.Names
      };

      this.loadTargetServers();
      this.migrateContainerVisible = true;
    },

    /** 显示迁移Compose弹窗 */
    handleMigrateCompose(row) {
      this.migrateComposeForm = {
        targetServerId: null,
        composePath: row.directory || row.path.substring(0, row.path.lastIndexOf('/'))
      };

      this.loadTargetServers();
      this.migrateComposeVisible = true;
    },

    /** 显示迁移Compose对话框 */
    showMigrateComposeDialog() {
      if (!this.composeDirPath) {
        this.$message.error('请先指定Compose目录');
        return;
      }

      this.migrateComposeForm = {
        targetServerId: null,
        composePath: this.composeDirPath
      };

      this.loadTargetServers();
      this.migrateComposeVisible = true;
    },

    /** 加载目标服务器列表 */
    loadTargetServers() {
      listServerOptions().then(response => {
        if (response.code === 200) {
          // 过滤掉当前服务器，只保留其他可用的服务器
          this.targetServers = response.data.filter(server =>
            server.serverId !== this.serverId
          );
        } else {
          this.$message.error('获取目标服务器列表失败');
        }
      }).catch(() => {
        this.$message.error('获取目标服务器列表失败');
      });
    },

    /** 提交迁移容器 */
    submitMigrateContainer() {
      if (!this.migrateContainerForm.targetServerId) {
        this.$message.error('请选择目标服务器');
        return;
      }

      this.migrateLoading = true;
      this.$modal.loading('正在迁移容器，这可能需要几分钟时间...');

      // 记录迁移开始时间
      const migrationStartTime = new Date();

      migrateDockerContainer(
        this.serverId,
        this.migrateContainerForm.targetServerId,
        this.migrateContainerForm.containerId
      ).then(response => {
        this.migrateLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          if (response.data.success) {
            this.$modal.msgSuccess('容器迁移成功');
            this.migrateContainerVisible = false;
          } else {
            this.$modal.msgError('容器迁移失败: ' + response.data.message);
          }
        } else {
          this.$modal.msgError('容器迁移请求失败: ' + response.msg);
        }
      }).catch(error => {
        // 检查是否是超时错误或请求时间超过60秒
        const currentTime = new Date();
        const requestTime = (currentTime - migrationStartTime) / 1000;

        if (error.message && error.message.includes('timeout') || requestTime > 60) {
          // 对于超时情况，通知用户迁移已在后台进行
          this.$modal.closeLoading();
          this.$modal.msgSuccess('迁移请求已提交，正在后台处理中，您可以继续使用系统');
          this.migrateContainerVisible = false;
          this.migrateLoading = false;

          // 开始轮询检查迁移状态
          this.pollMigrationStatus(this.migrateContainerForm.targetServerId);
        } else {
          // 对于其他错误，显示错误信息
          this.migrateLoading = false;
          this.$modal.closeLoading();
          this.$modal.msgError('容器迁移请求异常');
        }
      });
    },

    /** 轮询检查迁移状态 */
    pollMigrationStatus(targetServerId) {
      let pollCount = 0;
      const maxPolls = 30; // 最多轮询30次(5分钟)

      const checkStatus = () => {
        pollCount++;

        // 尝试获取目标服务器上的容器列表
        getDockerContainers(targetServerId).then(response => {
          if (response.code === 200) {
            this.$message.success('迁移已完成，容器列表已更新');
            // 停止轮询
            return;
          }
        }).catch(() => {
          // 发生错误，如果未达到最大轮询次数，继续轮询
          if (pollCount < maxPolls) {
            setTimeout(checkStatus, 10000); // 每10秒检查一次
          }
        });
      };

      // 开始轮询，延迟10秒开始第一次检查
      setTimeout(checkStatus, 10000);
    },

    /** 设置SSH免密登录 */
    setupSSHKeyAuth() {
      this.sshKeyAuthLoading = true;
      this.$modal.loading('正在设置SSH免密登录...');

      setupSSHKeyAuth(
        this.serverId,
        this.sshKeyAuthForm.targetServerId
      ).then(response => {
        this.sshKeyAuthLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          this.sshKeyAuthResult = response.data;
        } else {
          this.sshKeyAuthResult = {
            success: false,
            message: '请求失败: ' + response.msg
          };
        }
      }).catch(() => {
        this.sshKeyAuthLoading = false;
        this.$modal.closeLoading();
        this.sshKeyAuthResult = {
          success: false,
          message: '请求异常'
        };
      });
    },

    /** 生成SSH结果描述 */
    generateSSHResultDescription(result) {
      if (result.success) {
        return 'SSH密钥已成功配置，服务器间可以免密登录';
      } else {
        let description = '设置失败: ' + result.message;
        if (result.debug_info) {
          description += '\n调试信息: ' + result.debug_info;
        }
        if (result.sshd_config) {
          description += '\nSSH配置: ' + result.sshd_config;
        }
        if (result.permissions) {
          description += '\n权限信息: ' + result.permissions;
        }
        return description;
      }
    },

    /** 启动容器 */
    handleStartContainer(row) {
      if (!row || !row.ID) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.$modal.confirm('确认要启动容器 ' + row.Names + ' 吗？').then(() => {
        this.$modal.loading("正在启动容器...");
        startDockerContainer(this.serverId, row.ID).then(response => {
          this.$modal.closeLoading();
          if (response.code === 200) {
            const data = response.data;
            if (data.success) {
              this.$message.success('容器启动成功');
              this.getContainerList(); // 刷新容器列表
            } else {
              this.$message.error('容器启动失败: ' + data.message);
            }
          } else {
            this.$message.error('容器启动请求失败: ' + response.msg);
          }
        }).catch(() => {
          this.$modal.closeLoading();
          this.$message.error('容器启动请求异常');
        });
      });
    },

    /** 停止容器 */
    handleStopContainer(row) {
      if (!row || !row.ID) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.$modal.confirm('确认要停止容器 ' + row.Names + ' 吗？').then(() => {
        this.$modal.loading("正在停止容器...");
        stopDockerContainer(this.serverId, row.ID).then(response => {
          this.$modal.closeLoading();
          if (response.code === 200) {
            const data = response.data;
            if (data.success) {
              this.$message.success('容器停止成功');
              this.getContainerList(); // 刷新容器列表
            } else {
              this.$message.error('容器停止失败: ' + data.message);
            }
          } else {
            this.$message.error('容器停止请求失败: ' + response.msg);
          }
        }).catch(() => {
          this.$modal.closeLoading();
          this.$message.error('容器停止请求异常');
        });
      });
    },

    /** 删除容器 */
    handleRemoveContainer(row) {
      if (!row || !row.ID) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.$modal.confirm('确认要删除容器 ' + row.Names + ' 吗？此操作不可恢复！').then(() => {
        this.$modal.loading("正在删除容器...");
        removeDockerContainer(this.serverId, row.ID).then(response => {
          this.$modal.closeLoading();
          if (response.code === 200) {
            const data = response.data;
            if (data.success) {
              this.$message.success('容器删除成功');
              this.getContainerList(); // 刷新容器列表
            } else {
              this.$message.error('容器删除失败: ' + data.message);
            }
          } else {
            this.$message.error('容器删除请求失败: ' + response.msg);
          }
        }).catch(() => {
          this.$modal.closeLoading();
          this.$message.error('容器删除请求异常');
        });
      });
    },

    /** 查看容器日志 */
    handleContainerLogs(row) {
      if (!row || !row.ID) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.currentContainerId = row.ID;
      this.containerLogsVisible = true;
      this.refreshContainerLogs();
    },

    /** 刷新容器日志 */
    refreshContainerLogs() {
      if (!this.currentContainerId) {
        this.$message.error('容器ID不能为空');
        return;
      }

      this.$modal.loading('正在获取容器日志...');
      getDockerContainerLogs(this.serverId, this.currentContainerId, this.containerLogsLines).then(response => {
        this.$modal.closeLoading();
        if (response.code === 200) {
          if (response.data.success) {
            this.containerLogsContent = response.data.logs || '容器日志为空';
          } else {
            this.containerLogsContent = '获取日志失败: ' + response.data.message;
          }
        } else {
          this.containerLogsContent = '获取日志请求失败: ' + response.msg;
        }
      }).catch(() => {
        this.$modal.closeLoading();
        this.containerLogsContent = '获取日志请求异常';
      });
    },

    /** 检查Docker Compose是否已安装 */
    checkComposeInstalled() {
      executeCommand(this.serverId, "docker-compose --version || /usr/local/bin/docker-compose --version || docker compose version || $HOME/.docker/cli-plugins/docker-compose version || /root/.docker/cli-plugins/docker-compose version").then(response => {
        if (response.code === 200) {
          const data = response.data;
          this.composeInstalled = Boolean(data.success);
          
          if (data.success) {
            // 获取安装详情
            this.composeInstallDetails = {
              version: data.stdout
            };
            
            // 尝试获取更多安装详情
            this.getComposeInstallDetails();
          } else {
            this.composeInstallDetails = null;
          }
        }
      }).catch(() => {
        this.composeInstalled = false;
        this.composeInstallDetails = null;
      });
    },
    
    /** 获取Docker Compose安装详情 */
    getComposeInstallDetails() {
      // 检查可能的安装位置
      const checkLocations = [
        "$HOME/.docker/cli-plugins/docker-compose",
        "/root/.docker/cli-plugins/docker-compose",
        "/usr/local/lib/docker/cli-plugins/docker-compose",
        "/usr/local/bin/docker-compose",
        "/usr/bin/docker-compose"
      ];
      
      // 构建查找命令
      const locationCmd = checkLocations.map(loc => `[ -f ${loc} ] && echo "Found at ${loc}" && ls -la ${loc}`).join(" || ");
      
      executeCommand(this.serverId, locationCmd).then(response => {
        if (response.code === 200 && response.data.success) {
          if (!this.composeInstallDetails) {
            this.composeInstallDetails = {};
          }
          if (!this.composeInstallDetails.details) {
            this.composeInstallDetails.details = {};
          }
          this.composeInstallDetails.details.location = response.data.stdout;
          
          // 获取权限信息
          const permCmd = checkLocations.map(loc => `[ -f ${loc} ] && echo "Permissions for ${loc}:" && stat -c '%a %U %G' ${loc}`).join(" || ");
          
          executeCommand(this.serverId, permCmd).then(permResponse => {
            if (permResponse.code === 200 && permResponse.data.success) {
              this.composeInstallDetails.details.permissions = permResponse.data.stdout;
            }
          });
          
          // 检查是否是软链接
          const symlinkCmd = checkLocations.map(loc => `[ -L ${loc} ] && echo "Symlink for ${loc}:" && readlink -f ${loc}`).join(" || ");
          
          executeCommand(this.serverId, symlinkCmd).then(linkResponse => {
            if (linkResponse.code === 200 && linkResponse.data.success) {
              this.composeInstallDetails.details.symlink = linkResponse.data.stdout;
            }
          });
        }
      });
    },

    /** 安装Docker Compose */
    installDockerComposeHandler() {
      this.$modal.loading('正在安装Docker Compose，这可能需要几分钟时间...');

      installDockerCompose(this.serverId, this.composeVersion, this.composeInstallMethod).then(response => {
        this.$modal.closeLoading();
        if (response.code === 200) {
          const data = response.data;
          if (data.success) {
            this.composeInstalled = true;
            this.composeInstallDetails = data;
            this.$modal.msgSuccess('Docker Compose安装成功: ' + data.version);
            // 安装成功后刷新Compose文件列表
            this.searchComposeFiles();
          } else {
            this.$modal.msgError('Docker Compose安装失败: ' + data.message);
          }
        } else {
          this.$modal.msgError('请求失败: ' + response.msg);
        }
      }).catch(() => {
        this.$modal.closeLoading();
        this.$modal.msgError('安装请求异常，请稍后重试');
      });
    },

    /** 显示生成Compose文件弹窗 */
    handleGenerateCompose(row) {
      this.generateComposeForm = {
        containerId: row.ID,
        containerName: row.Names,
        outputPath: '/root/compose/docker-compose.yml',
        allContainers: false
      };

      this.generateComposeVisible = true;
    },

    /** 提交生成Compose文件 */
    submitGenerateCompose() {
      if (!this.generateComposeForm.outputPath) {
        this.$message.error('请输入输出路径');
        return;
      }

      this.generateComposeLoading = true;
      this.$modal.loading('正在生成Docker Compose文件...');

      generateDockerCompose(
        this.serverId,
        this.generateComposeForm.containerId,
        this.generateComposeForm.outputPath,
        this.generateComposeForm.allContainers
      ).then(response => {
        this.generateComposeLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          const data = response.data;
          if (data.success) {
            this.$modal.msgSuccess('Docker Compose文件生成成功');
            this.generateComposeVisible = false;

            // 显示生成的文件内容
            this.composeFileContent = data.content || '';
            if (!this.composeFileContent && data.message) {
              this.composeFileContent = '生成成功，但无内容返回：' + data.message;
            }
            this.composeFileContentVisible = true;

            // 刷新Compose文件列表
            if (this.dockerActiveTab === 'compose') {
              this.searchComposeFiles();
            }
          } else {
            this.$modal.msgError('生成失败：' + data.message);
          }
        } else {
          this.$modal.msgError('请求失败：' + response.msg);
        }
      }).catch(() => {
        this.generateComposeLoading = false;
        this.$modal.closeLoading();
        this.$modal.msgError('网络错误，请稍后重试');
      });
    },

    /** 导出所有容器为Docker Compose */
    handleGenerateAllCompose() {
      this.generateComposeForm = {
        containerId: '',
        containerName: 'all-containers',
        outputPath: '/root/compose/docker-compose.yml',
        allContainers: true
      };

      this.generateComposeVisible = true;
    },

    /** 运行Docker Compose文件 */
    handleRunCompose(composeFilePath, operation) {
      const title = operation === 'up' ? '启动' : '停止';
      this.$confirm(`确认要${title}该Docker Compose服务吗?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.runComposeLoading = true;
        runDockerCompose(this.serverId, composeFilePath, operation).then(response => {
          this.runComposeLoading = false;
          if (response.code === 200) {
            const data = response.data;
            if (data.success) {
              // 检查是否包含容器名称冲突的错误信息
              if (data.message && data.message.includes('Conflict. The container name')) {
                const conflict = this.checkContainerNameConflict(data.message);
                if (conflict) {
                  // 显示冲突解决对话框
                  this.containerConflictForm = {
                    containerName: conflict.name,
                    action: 'rename',
                    newName: `${conflict.name}-new`,
                    changePort: false,
                    portMapping: '',
                    composeFilePath: composeFilePath,
                    operation: operation
                  };
                  this.containerConflictVisible = true;
                  return;
                }
              }
              
              this.$modal.msgSuccess(`${title}操作成功: ${data.message || ''}`);
              // 无论是启动还是停止操作，都更新Docker容器列表
              this.getContainerList();
              // 刷新Compose文件列表
              this.searchComposeFiles();
            } else {
              // 检查失败消息中是否有容器名称冲突
              if (data.message && data.message.includes('Conflict. The container name')) {
                const conflict = this.checkContainerNameConflict(data.message);
                if (conflict) {
                  // 显示冲突解决对话框
                  this.containerConflictForm = {
                    containerName: conflict.name,
                    action: 'rename',
                    newName: `${conflict.name}-new`,
                    changePort: false,
                    portMapping: '',
                    composeFilePath: composeFilePath,
                    operation: operation
                  };
                  this.containerConflictVisible = true;
                  return;
                }
              }
              
              this.$modal.msgError(`${title}失败: ${data.message || '未知错误'}`);
            }
          } else {
            this.$modal.msgError(response.msg || `${title}请求失败`);
          }
        }).catch(() => {
          this.runComposeLoading = false;
          this.$modal.msgError(`${title}请求异常，请稍后重试`);
        });
      }).catch(() => {});
    },

    /** 删除Docker Compose文件 */
    handleDeleteComposeFile(filePath) {
      this.$confirm('确认要删除该Docker Compose文件吗？此操作不可恢复!', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.$modal.loading("正在删除文件...");
        const deleteCommand = `rm -f ${filePath}`;
        executeCommand(this.serverId, deleteCommand).then(response => {
          this.$modal.closeLoading();
          if (response.code === 200 && response.data.success) {
            this.$message.success('Docker Compose文件删除成功');
            // 刷新Compose文件列表
            this.searchComposeFiles();
          } else {
            this.$message.error('删除文件失败: ' + (response.data ? response.data.message || response.data.stderr : response.msg));
          }
        }).catch(() => {
          this.$modal.closeLoading();
          this.$message.error('删除文件请求异常');
        });
      }).catch(() => {});
    },

    /** 处理文件同步 */
    handleSyncFile(row) {
      this.syncFileForm = {
        sourcePath: row.path,
        targetServerId: null,
        targetPath: row.path,
        isDirectory: row.isDirectory
      };

      // 获取可用的目标服务器列表
      listServerOptions().then(response => {
        this.targetServers = response.data.filter(item => item.serverId !== this.serverId);
      });

      this.syncFileVisible = true;
    },

    /** 提交文件同步 */
    submitSyncFile() {
      if (!this.syncFileForm.targetServerId) {
        this.$message.error("请选择目标服务器");
        return;
      }

      if (!this.syncFileForm.targetPath) {
        this.$message.error("请输入目标路径");
        return;
      }

      this.syncLoading = true;
      syncFileBetweenServers(
        this.serverId,
        this.syncFileForm.targetServerId,
        this.syncFileForm.sourcePath,
        this.syncFileForm.targetPath
      ).then(response => {
        this.syncLoading = false;

        if (response.code === 200) {
          const result = response.data;

          if (result.success) {
            this.$modal.msgSuccess(result.message);
            this.syncFileVisible = false;
          } else {
            this.$modal.msgError(result.message);
          }
        } else {
          this.$modal.msgError(response.msg || "同步文件失败");
        }
      }).catch(() => {
        this.syncLoading = false;
      });
    },

    /** 显示迁移所有容器弹窗 */
    showMigrateAllContainersDialog() {
      this.migrateAllContainersForm = {
        targetServerId: null
      };
      this.loadTargetServers();
      this.migrateAllContainersVisible = true;
    },

    /** 显示迁移所有镜像弹窗 */
    showMigrateAllImagesDialog() {
      this.migrateAllImagesForm = {
        targetServerId: null
      };
      this.loadTargetServers();
      this.migrateAllImagesVisible = true;
    },

    /** 迁移所有容器 */
    submitMigrateAllContainers() {
      if (!this.migrateAllContainersForm.targetServerId) {
        this.$message.error('请选择目标服务器');
        return;
      }

      this.migrateLoading = true;
      this.$modal.loading('正在迁移所有容器，这可能需要较长时间...');

      migrateAllDockerContainers(
        this.serverId,
        this.migrateAllContainersForm.targetServerId
      ).then(response => {
        this.migrateLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          if (response.data.success) {
            this.$modal.msgSuccess('所有容器迁移请求已提交，将在后台处理');
            this.migrateAllContainersVisible = false;
          } else {
            this.$modal.msgError('容器迁移失败: ' + response.data.message);
          }
        } else {
          this.$modal.msgError('容器迁移请求失败: ' + response.msg);
        }
      }).catch(() => {
        this.migrateLoading = false;
        this.$modal.closeLoading();
        this.$modal.msgError('容器迁移请求异常');
      });
    },

    /** 迁移所有镜像 */
    submitMigrateAllImages() {
      if (!this.migrateAllImagesForm.targetServerId) {
        this.$message.error('请选择目标服务器');
        return;
      }

      this.migrateLoading = true;
      this.$modal.loading('正在迁移所有镜像，这可能需要较长时间...');

      // 这里应该有一个真实的API调用
      // 由于API调用不完整，这里暂时模拟一个成功响应
      setTimeout(() => {
        this.migrateLoading = false;
        this.$modal.closeLoading();
        this.$modal.msgSuccess('所有镜像迁移请求已提交，将在后台处理');
        this.migrateAllImagesVisible = false;
      }, 1000);
    },

    /** 提交迁移Compose */
    submitMigrateCompose() {
      if (!this.migrateComposeForm.targetServerId) {
        this.$message.error('请选择目标服务器');
        return;
      }

      this.migrateLoading = true;
      this.$modal.loading('正在迁移Compose配置...');

      migrateDockerCompose(
        this.serverId,
        this.migrateComposeForm.targetServerId,
        this.migrateComposeForm.composePath
      ).then(response => {
        this.migrateLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          if (response.data.success) {
            this.$modal.msgSuccess('Compose配置迁移成功');
            this.migrateComposeVisible = false;
          } else {
            this.$modal.msgError('Compose配置迁移失败: ' + response.data.message);
          }
        } else {
          this.$modal.msgError('Compose配置迁移请求失败: ' + response.msg);
        }
      }).catch(() => {
        this.migrateLoading = false;
        this.$modal.closeLoading();
        this.$modal.msgError('Compose配置迁移请求异常');
      });
    },

    /** 迁移镜像 */
    submitMigrateImage() {
      if (!this.migrateImageForm.targetServerId) {
        this.$message.error('请选择目标服务器');
        return;
      }

      this.migrateLoading = true;
      this.$modal.loading('正在迁移镜像，这可能需要几分钟时间...');

      migrateDockerImage(
        this.serverId,
        this.migrateImageForm.targetServerId,
        this.migrateImageForm.imageId
      ).then(response => {
        this.migrateLoading = false;
        this.$modal.closeLoading();

        if (response.code === 200) {
          if (response.data.success) {
            this.$modal.msgSuccess('镜像迁移成功');
            this.migrateImageVisible = false;
          } else {
            this.$modal.msgError('镜像迁移失败: ' + response.data.message);
          }
        } else {
          this.$modal.msgError('镜像迁移请求失败: ' + response.msg);
        }
      }).catch(() => {
        this.migrateLoading = false;
        this.$modal.closeLoading();
        this.$modal.msgError('镜像迁移请求异常');
      });
    },

    /** 获取已安装软件列表 */
    getInstalledSoftwareList() {
      this.installedSoftwareLoading = true;
      getInstalledSoftwarePackages(this.serverId, this.installedSearchKeyword).then(response => {
        this.installedSoftwareLoading = false;
        if (response.code === 200) {
          this.installedSoftwareList = response.data;
        } else {
          this.$message.error('获取已安装软件列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.installedSoftwareLoading = false;
        this.$message.error('获取已安装软件列表请求异常');
      });
    },

    /** 搜索已安装软件 */
    searchInstalledSoftware() {
      this.getInstalledSoftwareList();
    },

    /** 获取可用软件列表 */
    getAvailableSoftwareList() {
      this.availableSoftwareLoading = true;
      getAvailableSoftwarePackages(this.serverId, this.availableSearchKeyword).then(response => {
        this.availableSoftwareLoading = false;
        if (response.code === 200) {
          this.availableSoftwareList = response.data;
        } else {
          this.$message.error('获取可用软件列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.availableSoftwareLoading = false;
        this.$message.error('获取可用软件列表请求异常');
      });
    },

    /** 搜索可用软件 */
    searchAvailableSoftware() {
      this.getAvailableSoftwareList();
    },

    /** 显示全部更新对话框 */
    showUpdateAllDialog() {
      this.$confirm('确认要更新所有软件包吗？此操作可能需要较长时间。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.softwareOperationVisible = true;
        this.softwareOperationLogs = '';
        this.softwareOperationProgress = 0;
        this.softwareOperationStatus = '';
        this.softwareOperationRunning = true;
        
        // 模拟更新进度
        this.simulateUpdateProgress();
      }).catch(() => {});
    },

    /** 模拟更新进度 */
    simulateUpdateProgress() {
      let progress = 0;
      this.softwareOperationTimer = setInterval(() => {
        progress += 10;
        this.softwareOperationProgress = progress;
        this.softwareOperationLogs += '正在更新软件包... ' + progress + '%\n';
        
        if (progress >= 100) {
          clearInterval(this.softwareOperationTimer);
          this.softwareOperationStatus = 'success';
          this.softwareOperationRunning = false;
          this.softwareOperationLogs += '所有软件包已更新完成\n';
        }
      }, 1000);
    },

    /** 关闭软件操作对话框 */
    closeSoftwareOperation() {
      if (this.softwareOperationTimer) {
        clearInterval(this.softwareOperationTimer);
      }
      this.softwareOperationVisible = false;
    },

    /** 检查错误信息中是否包含容器名称冲突 */
    checkContainerNameConflict(errorMessage) {
      if (!errorMessage) return null;
      
      // 匹配容器名冲突错误信息
      const conflictRegex = /The container name "([^"]+)" is already in use by container "([^"]+)"/;
      const match = errorMessage.match(conflictRegex);
      
      if (match) {
        return {
          name: match[1].replace(/^\//, ''), // 移除名称开头的斜杠
          id: match[2]
        };
      }
      
      return null;
    },

    /** 解决容器名称冲突 */
    handleResolveContainerConflict() {
      if (this.containerConflictForm.action === 'rename' && !this.containerConflictForm.newName) {
        this.$message.error('请输入新的容器名称');
        return;
      }
      
      this.containerConflictLoading = true;
      
      if (this.containerConflictForm.action === 'remove') {
        // 先停止并删除已存在的容器
        executeCommand(
          this.serverId, 
          `docker stop ${this.containerConflictForm.containerName} && docker rm ${this.containerConflictForm.containerName}`
        ).then(response => {
          if (response.code === 200 && response.data.success) {
            // 容器删除成功，再次尝试启动
            this.containerConflictVisible = false;
            this.containerConflictLoading = false;
            // 重新尝试启动
            this.handleRunCompose(this.containerConflictForm.composeFilePath, this.containerConflictForm.operation);
          } else {
            this.containerConflictLoading = false;
            this.$message.error('删除冲突容器失败: ' + (response.data ? response.data.stderr || response.data.message : response.msg));
          }
        }).catch(() => {
          this.containerConflictLoading = false;
          this.$message.error('删除冲突容器请求异常');
        });
      } else {
        // 读取compose文件内容
        readDockerComposeFile(this.serverId, this.containerConflictForm.composeFilePath).then(response => {
          if (response.code === 200) {
            let content = '';
            if (response.msg && typeof response.msg === 'string' && response.msg.includes('version:')) {
              content = response.msg;
            } else {
              content = response.data || '';
            }
            
            if (!content) {
              this.containerConflictLoading = false;
              this.$message.error('读取Compose文件失败，文件内容为空');
              return;
            }
            
            // 修改文件内容，替换容器名称
            let modifiedContent = content;
            const containerName = this.containerConflictForm.containerName;
            const newName = this.containerConflictForm.newName;
            
            // 简单替换容器名称
            const containerNameRegex = new RegExp(`container_name:\\s*['"]?${containerName}['"]?`, 'g');
            modifiedContent = modifiedContent.replace(containerNameRegex, `container_name: "${newName}"`);
            
            // 如果需要修改端口
            if (this.containerConflictForm.changePort && this.containerConflictForm.portMapping) {
              const portMappings = this.containerConflictForm.portMapping.split(',');
              let portsSection = 'ports:\n';
              
              portMappings.forEach(mapping => {
                const [host, container] = mapping.split(':');
                if (host && container) {
                  portsSection += `      - "${host}:${container}"\n`;
                }
              });
              
              // 尝试替换端口部分，这是一个简化的实现，可能需要更复杂的逻辑来处理YAML正确
              const portsRegex = /ports:\s*(\n\s*-\s*"?\d+:\d+"?\s*)+/g;
              if (modifiedContent.match(portsRegex)) {
                modifiedContent = modifiedContent.replace(portsRegex, portsSection);
              } else {
                // 如果没有找到端口部分，可能需要添加
                // 这里的逻辑需要根据实际情况进行调整
              }
            }
            
            // 创建一个临时文件保存修改后的内容
            const tempFilePath = `${this.containerConflictForm.composeFilePath}.temp`;
            executeCommand(
              this.serverId,
              `cat > ${tempFilePath} << 'EOL'\n${modifiedContent}\nEOL`
            ).then(writeResponse => {
              if (writeResponse.code === 200 && writeResponse.data.success) {
                // 备份原文件
                executeCommand(
                  this.serverId,
                  `cp ${this.containerConflictForm.composeFilePath} ${this.containerConflictForm.composeFilePath}.bak && ` +
                  `mv ${tempFilePath} ${this.containerConflictForm.composeFilePath}`
                ).then(moveResponse => {
                  if (moveResponse.code === 200 && moveResponse.data.success) {
                    this.containerConflictVisible = false;
                    this.containerConflictLoading = false;
                    
                    // 重新尝试启动
                    this.$message.success('Compose文件已修改，正在尝试启动...');
                    this.handleRunCompose(this.containerConflictForm.composeFilePath, this.containerConflictForm.operation);
                  } else {
                    this.containerConflictLoading = false;
                    this.$message.error('更新Compose文件失败: ' + (moveResponse.data ? moveResponse.data.stderr || moveResponse.data.message : moveResponse.msg));
                  }
                }).catch(() => {
                  this.containerConflictLoading = false;
                  this.$message.error('更新Compose文件请求异常');
                });
              } else {
                this.containerConflictLoading = false;
                this.$message.error('写入临时文件失败: ' + (writeResponse.data ? writeResponse.data.stderr || writeResponse.data.message : writeResponse.msg));
              }
            }).catch(() => {
              this.containerConflictLoading = false;
              this.$message.error('写入临时文件请求异常');
            });
          } else {
            this.containerConflictLoading = false;
            this.$message.error('读取Compose文件失败: ' + response.msg);
          }
        }).catch(() => {
          this.containerConflictLoading = false;
          this.$message.error('读取Compose文件请求异常');
        });
      }
    },

    /** 获取Docker容器模板列表 */
    getDockerTemplates() {
      this.templateLoading = true;
      listDockerTemplate().then(response => {
        this.templateLoading = false;
        if (response.code === 200) {
          this.dockerTemplates = response.data;
        } else {
          this.$message.error('获取容器模板列表失败: ' + response.msg);
        }
      }).catch(() => {
        this.templateLoading = false;
        this.$message.error('获取容器模板列表失败');
      });
    },
    
    /** 部署容器模板 */
    handleDeployTemplate(row) {
      this.selectedTemplate = row;
      this.templateForm = {
        templateId: row.templateId,
        templateName: row.templateName,
        containerName: row.templateName + '-' + new Date().getTime(),
        customParams: {
          portMappings: '',
          volumeMappings: '',
          environmentVars: ''
        }
      };
      this.templateDeployVisible = true;
    },
    
    /** 查看容器模板详情 */
    handleViewTemplate(row) {
      this.selectedTemplate = row;
      this.templateDetailVisible = true;
    },
    
    /** 取消部署容器模板 */
    cancelTemplateDeploy() {
      this.templateDeployVisible = false;
    },
    
    /** 提交部署容器模板 */
    submitTemplateForm() {
      this.templateDeployLoading = true;
      
      // 过滤空的自定义参数
      let customParams = {};
      if (this.templateForm.customParams.portMappings) {
        customParams.portMappings = this.templateForm.customParams.portMappings;
      }
      if (this.templateForm.customParams.volumeMappings) {
        customParams.volumeMappings = this.templateForm.customParams.volumeMappings;
      }
      if (this.templateForm.customParams.environmentVars) {
        customParams.environmentVars = this.templateForm.customParams.environmentVars;
      }
      
      // 构建请求参数
      const data = {
        containerName: this.templateForm.containerName,
        customParams: Object.keys(customParams).length > 0 ? customParams : null
      };
      
      createContainerFromTemplate(this.serverId, this.templateForm.templateId, data).then(response => {
        this.templateDeployLoading = false;
        if (response.data.success) {
          this.$modal.msgSuccess('容器部署成功');
          this.templateDeployVisible = false;
          // 部署成功后刷新容器列表
          this.getContainerList();
        } else {
          this.$modal.msgError('容器部署失败: ' + response.data.message);
        }
      }).catch(() => {
        this.templateDeployLoading = false;
      });
    },
    
    /** 跳转到模板管理页面 */
    goToTemplateManage() {
      this.$router.push('/system/dockerTemplate/index');
    }
  }
};
</script>

<style lang="scss" scoped>
.server-detail {
  padding: 20px;
  .server-form {
    margin-bottom: 20px;
  }
  .command-panel {
    margin-top: 10px;
    .command-input {
      margin-bottom: 10px;
    }
    .command-output {
      min-height: 200px;
      max-height: 400px;
      overflow-y: auto;
      background-color: #f5f5f5;
      padding: 10px;
      border-radius: 4px;
      font-family: monospace;
      white-space: pre-wrap;
      word-break: break-all;
    }
  }
  .detail-content {
    white-space: pre-wrap;
    word-break: break-all;
    font-family: monospace;
    background-color: #f5f5f5;
    padding: 10px;
    max-height: 600px;
    overflow-y: auto;
    border-radius: 4px;
  }
  .empty-content {
    text-align: center;
    padding: 20px;
    color: #909399;
  }
  .file-list-container {
    margin-top: 10px;
    .file-list {
      max-height: 500px;
      overflow-y: auto;
    }
  }
}
</style>
